/**************************************************************

Copyright Astrium Services GEO-Information / Spot Image
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

 ***************************************************************/
package com.spotimage.catalog.client.ui.tab;

import com.google.gwt.user.client.Cookies;
import com.smartgwt.client.data.RecordList;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.tab.Tab;
import com.spotimage.catalog.client.ajax.Requester;
import com.spotimage.catalog.client.event.DeselectedSelectionFootprintEvent;
import com.spotimage.catalog.client.event.MoveToSelectionEvent;
import com.spotimage.catalog.client.event.EventBus;
import com.spotimage.catalog.client.event.RemoveFromSelectionEvent;
import com.spotimage.catalog.client.event.SelectedSelectionFootprintEvent;
import com.spotimage.catalog.client.event.SelectionSearchResultEvent;
import com.spotimage.catalog.client.shared.Scene;
import com.spotimage.catalog.client.ui.SelectionExportWindow;
import com.spotimage.catalog.client.ui.Ui;
import com.spotimage.catalog.client.ui.listgrid.SelectionListGrid;
import com.spotimage.catalog.client.ui.listgrid.SceneListGridRecord;
import com.spotimage.catalog.client.util.Util;

/**
 * Selection tab
 */
public class SelectionTab extends Tab implements MoveToSelectionEvent.Handler, 
													RemoveFromSelectionEvent.Handler,
													SelectedSelectionFootprintEvent.Handler,
													DeselectedSelectionFootprintEvent.Handler,
													SelectionSearchResultEvent.Handler {
	
	private static final String COOKIE_METADATAID_SEPARATOR = ",";

	/** selection cookie name */
	private static final String COOKIE_NAME = "selection";

	/** tab title */
	private static final String TITLE = "Selection";
	
	/** listGrid of cart's scenes */
	private SelectionListGrid listGrid;

	/**
	 * Build UI.
	 */
	public SelectionTab() {
		super(TITLE, Util.getImageUrl("cart.png"));
		
		EventBus.getInstance().addHandler(MoveToSelectionEvent.TYPE, this);
		EventBus.getInstance().addHandler(RemoveFromSelectionEvent.TYPE, this);
		EventBus.getInstance().addHandler(SelectedSelectionFootprintEvent.TYPE, this);
		EventBus.getInstance().addHandler(DeselectedSelectionFootprintEvent.TYPE, this);
		EventBus.getInstance().addHandler(SelectionSearchResultEvent.TYPE, this);
		
		listGrid = new SelectionListGrid();
		setTitle();
		
		VLayout layout = new VLayout(5);
		layout.setPadding(new Integer(5));
		layout.setBackgroundColor(Ui.BACKGROUND_COLOR);
		layout.setBorder("1px solid " + Ui.BORDER_COLOR);
		layout.addMember(listGrid);
		
		IButton exportButton = new IButton();
		exportButton.setTitle("Export selection");
		exportButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				new SelectionExportWindow(listGrid);
			}
		});
		layout.addMember(exportButton);
		
		setPane(layout);
		
		getSelectionFromCookie();
	}

	/** 
	 * set title with selection items number.
	 * @param itemsNumber
	 */
	private void setTitle() {
		super.setTitle(TITLE + " (" + listGrid.getRecords().length + ")");
	}

	/**
	 * Receive {@link MoveToSelectionEvent} and add scene items to selection.
	 */
	//@Override
	public void onMoveToSelection(MoveToSelectionEvent e) {
		SceneListGridRecord slgr = e.getItem();
		RecordList recordList = listGrid.getRecordList();
		int foundRecordIndex = recordList.findIndex("id", slgr.getId());
		if (foundRecordIndex == -1) {
			listGrid.addData(slgr);
		} 
		setTitle();
		setCookie();
	}

	/**
	 * Receive {@link RemoveFromSelectionEvent} and remove scene items to selection.
	 */
	//@Override
	public void onRemoveFromSelection(RemoveFromSelectionEvent e) {
		setTitle();
		setCookie();
	}
	
	/**
	 * Receive {@link SelectedSelectionFootprintEvent} and select the scene items in list.
	 */
	//@Override
	public void onSelectedSelectionFootprint(SelectedSelectionFootprintEvent e) {
		RecordList recordList = listGrid.getRecordList();
		int foundRecordIndex = recordList.findIndex("id", e.getId());
		if (foundRecordIndex != -1) {
			listGrid.deselectAllRecords();
			listGrid.selectRecord(foundRecordIndex);
		} 
	}

	/**
	 * Receive {@link DeselectedSelectionFootprintEvent} and deselect scene items in list.
	 */
	//@Override
	public void onDeselectedSelectionFootprint(DeselectedSelectionFootprintEvent e) {
		listGrid.deselectAllRecords();
	}
	
	/**
	 * Save selection data in JSON cookie.
	 */
	private void setCookie() {
		String cookieValue = "";
		RecordList recordList = listGrid.getRecordList();
		for (int i = 0; i < recordList.getLength(); i++) {
			if (!cookieValue.equals("")) cookieValue += COOKIE_METADATAID_SEPARATOR;
			SceneListGridRecord record = (SceneListGridRecord) recordList.get(i);
			cookieValue += getMetadataId(record.getMetadataUrl());
		}
		Cookies.setCookie(COOKIE_NAME, cookieValue);
	}
	
	/**
	 * Returns metadata id from metadataUrl.<br>
	 * For example if metadata is "http://daliis.spotimage.fr/dali-rest-api/Dali.svc/Scenes/S/1500000/Shift0?sk=hWNCKX2Cs_-yzC3JkUZmpQ::",
	 * it will return "1500000".
	 * @param metadataUrl
	 * @return
	 */
	private String getMetadataId(String metadataUrl) {
		String idStart = "Scenes/";
		String[] split = metadataUrl.split(idStart);
		String[] split2 = split[1].split("[?]");
		return idStart + split2[0];
	}

	/**
	 * Get selection from cookie.
	 */
	private void getSelectionFromCookie() {
		String cookieValue = Cookies.getCookie(COOKIE_NAME);
		// get scene from metadata id from cookie
		if (cookieValue != null) {
			int start = 0;
			int end;
			while ((end = cookieValue.indexOf(COOKIE_METADATAID_SEPARATOR, start)) != -1) {
				String metaDataId = cookieValue.substring(start, end);
				start = end + 1;
				Requester.send(metaDataId, new SelectionSearchResultEvent(), false);
			}
			String metaDataId = cookieValue.substring(start, cookieValue.length());
			Requester.send(metaDataId, new SelectionSearchResultEvent(), false);
		}
	}

	/**
	 * Receive {@link SelectionSearchResultEvent} and populate selection.
	 */
	//@Override
	public void onSelectionSearchResult(SelectionSearchResultEvent e) {
		Scene scene = e.getSearchResult().getScenes().get(0);
		SceneListGridRecord record = new SceneListGridRecord(scene.getId(), scene.getCloudCoverPercentage(), 
				Util.getDateFromISO8601(scene.getAcquisitionDateString()), scene.getImageUrl(), scene.getSatellite(),
				scene.getSnowCoverPercentage(), scene.getMetadataUrl(), scene.getShift(), scene.getMinShift(), scene.getMaxShift(), 
				scene.getArchivingStation(), scene.getUpperLeft(), scene.getUpperRight(), scene.getLowerLeft(), scene.getLowerRight());
		listGrid.addData(record);
		setTitle();
		EventBus.getInstance().fireEvent(new MoveToSelectionEvent(record));
	}

}
